package com.itheima.d2_polymorphism;

/**
 * 1、使用多态有什么好处？存在什么问题？
 * 可以解耦合，扩展性更强； 比如对象多态方面，业务更改就直接改父类接收的对象
 * 使用父类类型的变量作为方法的形参时，可以接收一切子类对象。
 * 多态下不能直接调用子类的独有方法。
 *
 * 2、类型转换有几种形式？能解决什么问题？
 * 自动类型转换、强制类型转换。
 * 可以把对象转换成其真正的类型，从而解决了多态下不能调用子类独有方法的问题。
 *
 * 3、强制类型转换需要注意什么？
 * 存在继承/实现时，就可以进行强制类型转换，编译阶段不会报错。
 * 但是，运行时，如果发现对象的真实类型与强转后的类型不同会报错（ClassCastException）。
 * 4、强制类型转换前？Java建议我们做什么事情？
 * 使用instanceof判断当前对象的真实类型：对象 instanceof 当前对象的真实类型 。
 */
public class Test {
    public static void main(String[] args) {
        // 目标：理解多态的好处
        // 好处1：可以实现解耦合，右边对象可以随时切换，后续业务随机改变
        People p1 = new Student();    //这个就是自动类型转换
        p1.run();  //run是重写了父类的，就近原则，调用子类的run方法
        //识别技巧：编译看左边，运行看右边  (意思是指真实运行时会看真正的对象那边)。所以编译的时候看people类里面没有子类的test方法
        // p1.test(); // 多态下存在的问题：无法直接调用子类的独有功能。

        // 强制类型转换
        Student s1 = (Student) p1;
        s1.test();


        // 强制类型转换可能存在的问题：编译阶段有继承或者实现关系就可以强制转换，但是运行时可能出现类型转换异常
        // Teacher t1 = (Teacher) p1; // 编译阶段没有报错，但是运行时出现了: ClassCastException
        if(p1 instanceof Student) {
            Student s2 = (Student) p1;
            s2.test();
        }else if(p1 instanceof Teacher) {
            Teacher t2 = (Teacher) p1;
            t2.teach();
        }

        System.out.println("-----------------------");
        // 好处2：可以使用父类类型的变量作为形参，可以接收一切子类对象。
        Student s = new Student();
        go(s);

        Teacher t = new Teacher();
        go(t);
    }


    public static void go(People p){  //使用父类类型的变量作为形参，可以接收一切子类对象
        //此时根本不知道people类型的形参，接收的是什么类型的对象，就需要判断
        p.run();
        if(p instanceof Student) {
            Student s = (Student) p;
            s.test();
        }else if(p instanceof Teacher){
            Teacher t = (Teacher) p;
            t.teach();
        }
    }
}
